package utils;

import lombok.SneakyThrows;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MyRobot {
    public Robot robot;

    @SneakyThrows
    public MyRobot() {
        robot = new Robot();
        robot.setAutoDelay(500);
    }

    public MyRobot(Robot robot) {
        this.robot = robot;
    }

    /**
     * ctrl+v
     * @param robot
     */
    public void paste(Robot robot) {
        robot.keyPress(KeyEvent.VK_CONTROL);
        robot.keyPress(KeyEvent.VK_V);
        robot.keyRelease(KeyEvent.VK_V);
        robot.keyRelease(KeyEvent.VK_CONTROL);
    }

    public void enter(Robot robot) {
        // 模拟按下Enter键
        robot.keyPress(KeyEvent.VK_ENTER);
        robot.keyRelease(KeyEvent.VK_ENTER);
    }

    /**
     * 设置粘贴板
     * @param text
     */
    public void inputText(String text) {
        setClipboardText(text);
        paste(robot);
    }

    private void setClipboardText(String text) {
        StringSelection selection = new StringSelection(text);
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(selection, null);
        System.out.println("Text successfully copied to clipboard");
    }

    /**
     * 模拟鼠标左键单击
     */
    public void click() {
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    }

    @SneakyThrows
    public void moveAndClick(org.opencv.core.Point point) {
        System.out.println(point.x);
        System.out.println(point.y);
        robot.mouseMove((int) point.x, (int) point.y);
        Thread.sleep(200);
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    }

    /**
     * 打开app
     * @param appPath
     */
    public void openApp(String appPath) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(appPath);
            processBuilder.start();
            System.out.println("打开" + appPath + "成功");
        } catch (IOException e) {
            System.err.println("无法打开 " + appPath + ",错误信息:" + e.getMessage());
        }
    }

    public void screenCapture(Robot robot) throws IOException {
        // 获取屏幕大小
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        // 创建BufferedImage对象，捕获屏幕图像
        BufferedImage screenCapture = robot.createScreenCapture(new Rectangle(screenSize));
        // 保存图像到文件
        File outputFile = new File("src/main/resources/screenshot/screen.png");
        ImageIO.write(screenCapture, "png", outputFile);
        System.out.println("屏幕截图已保存到: " + outputFile.getAbsolutePath());
    }

    /**
     * 利用opencv查找轮廓
     * @param image
     * @param threshold1
     * @param threshold2
     * @return
     */
    public List<MatOfPoint> findContours(Mat image, double threshold1, double threshold2) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 转换图像为灰度
        Mat gray = new Mat();
        Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);
        // 进行边缘检测
        Mat edges = new Mat();
//        Imgproc.Canny(gray, edges, 50, 150);
        Imgproc.Canny(gray, edges, threshold1, threshold2);
        // 查找轮廓
        List<MatOfPoint> contours = new ArrayList<>();
        Mat hierarchy = new Mat();
        // RETR_EXTERNAL 只检测外围的大轮廓
        // RETR_LIST 所有的 从右往左,从里往外检测
        // RETR_CCOMP每层最多2级
        // RETR_TREE树形返回
        Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
//        contours.sort(new Comparator<MatOfPoint>() {
//            @Override
//            public int compare(MatOfPoint o1, MatOfPoint o2) {
//            }
//        });
        System.out.println(contours.size());
        return contours;
    }

    /**
     * 从原图上切图并保存
     * @param image      原图
     * @param rect       区域
     * @param outputPath 切图保存路径
     */
    public void cut(Mat image, Rect rect, String outputPath) {
        Mat croppedImage = new Mat(image, rect);
        // 保存裁剪出的图像到文件
        Imgcodecs.imwrite(outputPath, croppedImage);
    }
}
